#!/usr/bin/env python
# -*- coding: utf-8 -*-

from core.utils.singleton import singleton
from xml.etree.ElementTree import ElementTree
import shutil
import os


PROJECT_DATALEVEL=0


class DataObject:
    def __init__(self):
        self._sections={}
        self._category={}
    
    def readData(self,xmlData):
        self._xml=xmlData
        sections=self._xml.findall("section")
        for section in sections:
            
            sectionName=section.get("name")
            self._sections[sectionName]={}
            datas=section.findall("data")
            for data in datas:
                dataName=data.get("name")
                #print (dataName,data.find("value").text)
                d=DataInfos(sectionName,dataName,data.find("value").text,data.find("type").text,data.find("options").text,data.find("category").text)#,data.find("help").text
                self._sections[sectionName][dataName]=d
    
    def getData(self,section,name,defaultValue=None,defaultValues=None,defaulCategory="Generic"):
        #section=section[0].capitalize()+section[1:]

        if self._sections.has_key(section) and self._sections[section].has_key(name):
            data=self._sections[section][name]
        else:
            data=DataInfos(section,name,defaultValue,None,defaultValues,defaulCategory)
            self.addDataInfos(data)
        return data
    
    
    def hasSections(self,section):
        return self._sections.has_key(section)
        
    def getSections(self):
        ret=self._sections.keys()
        #ret.remove("Druid")
        #ret.insert(0,"Druid")
        return ret
    
    
    def setData(self,section,name,value=None,values=None,category=None):
        #section=section[0].capitalize()+section[1:]
        if self._sections.has_key(section) and self._sections[section].has_key(name):
            data=self._sections[section][name]
            if value:
                data.value=value
            if values:
                data.values=values
            if category:
                data.category=category
        else:
            data=DataInfos(section,name,value,values,category)
            self.addDataInfos(data)
        return data
    
    
    def addDataInfos(self,dataInfos):
        if not self._sections.has_key(dataInfos.section):
            self._sections[dataInfos.section]={}
        if not self._category.has_key(dataInfos.section):
            self._category[dataInfos.section]={}
        if not self._sections[dataInfos.section].has_key(dataInfos.name):
            self._sections[dataInfos.section][dataInfos.name]=dataInfos
            self._category[dataInfos.section][dataInfos.category]=1
            
    def setValue(self,section,name,value):
        self._sections[section][name].value=value
        #self.saveOption(self._sections[section][name])
    
    def hasValue(self,section,name):
        return self._sections.has_key(section) and self._sections[section].has_key(name)
      
    def getValue(self,section,name):
        return self._sections[section][name].value
        
    def getDatas(self,section):
        return self._sections[section]
        
    def getCategories(self,section):
        return self._category[section].keys()
        
        
    def _createData(self):
        if not os.path.exists(self.home):
            os.mkdir(self.home)
        #open("data/userdata.xml","w+")
        shutil.copyfile("data/userdata.xml", self.home+'/userdata.xml')

    def getStringXml(self,level=0):
        xml="\n"+("\t"*level)+"<data>"
        for sectionName in self._sections:
            xml+="\n\t"+("\t"*level)+"<section name='"+sectionName+"'>"
            section= self._sections[sectionName]
            for dataName in section:
                xml+="\n\t\t"+("\t"*level)+"<data name='"+dataName+"'>"
                xml+=section[dataName].getXMLString()
                xml+="\n\t\t"+("\t"*level)+"</data>"
            xml+="\n\t"+("\t"*level)+"</section>"
        xml+="\n"+("\t"*level)+"</data>"
        return xml

    def copyData(self,dataObject):
        for section in dataObject.getSections():
            for data in dataObject.getDatas(section):
                self.addDataInfos(data.clone())

@singleton
class DataMangager(DataObject):
    def __init__(self):
        DataObject.__init__(self)
        self.home=os.getenv('HOME') or os.getenv('LOCALAPPDATA')
        self.home+='/.druid'
        self._priorData=None
        if not os.path.exists(self.home+'/userdata.xml'):
            self._createData()
        self.readData(ElementTree(None,self.home+'/userdata.xml'))
    
    #def getData(self,section,name):
    #    return self._sections[dataInfos.section][dataInfos.name]
    def addPriorDataTool(self,dataTool):
        return
        self._priorData=dataTool
    
    def removePriorDataTool(self):
        self._priorData=None
    
    def getData(self,section,name,defaultValue=None,defaultValues=None,defaulCategory="Generic"):
        DataObject.getData(self,section,name,defaultValue,defaultValues,defaulCategory)
        if self._priorData and self._priorData.hasValue(section,name):
            return self._priorData.getData(section,name)
        return DataObject.getData(self,section,name,defaultValue,defaultValues,defaulCategory)
    
    
    def getDataInSections(self,sections,name,defaultValue=None,defaultValues=None,defaulCategory="Generic"):
        for section in sections:
            if self.hasValue(section,name):
                return self.getData(section,name)
        return self.getData(sections[-1],name,defaultValue,defaultValues,defaulCategory)
    
    def getValueInSections(self,sections,name):
        for section in sections:
            if self.hasValue(section,name):
                return self.getValue(section,name)
        
    def getValue(self,section,name):
        if self._priorData and self._priorData.hasValue(section,name):
            return self._priorData.getValue(section,name)
        return DataObject.getValue(self,section,name)
    
    def save(self):
        f=open(self.home+'/userdata.xml','w')
        xml='<?xml version="1.0" encoding="UTF-8"?>'
        xml+=self.getStringXml()
        f.write(xml)
        f.close()




class DataInfos:
    
    INT="int"
    FLOAT="float"
    BOOL="bool"
    DIR="dir"
    STRING="string"
    FILE="file"
    FILES="files"
    ENUM="enum"
    FIX="fix"
    LIST="list"
    
    def __init__(self,section,name,value,type_=None,options=None,category="Generic",help_=""):
        self.section=section
        self.name=name
        self.value=value
        self.category=category
        self.help=help_
        self.type=type_
        self.options=options
        if not self.type:
            self.findType()
        #print("*************DataInfos1",self.name,self.value)    
        self.valueCorrection()
        self.temp=None
        #print("*************DataInfos",self.name,self.value)


    def valueCorrection(self):
        if self.type==DataInfos.BOOL:
              self.value = (self.value==True or self.value=="True")
        elif self.type==DataInfos.ENUM:
            if not self.value:
                self.value=0
            if type(self.value) == str:
                self.value = eval(self.value)
            if type(self.options) == str:
                self.options = eval(self.options)
        elif self.type == DataInfos.INT:
            try:
                self.value = int(self.value)
            except:
                self.value = 0
        elif self.type == DataInfos.FLOAT:
            try:
                self.value = float(self.value)
            except:
                self.value=0.0
        elif self.type == DataInfos.DIR:
            if not self.value:
                self.value=""
        elif self.type == DataInfos.FILE:
            if not self.value:
                self.value=""
        elif self.type == DataInfos.LIST:
            if not self.value:
                self.value = []
            elif type(self.value) == str:
                self.value = self.value.split(",")

    def findType(self):
        if type(self.value)==bool :
            self.type=DataInfos.BOOL
        elif type(self.value)==str:
            self.type=DataInfos.STRING
        elif type(self.value)==int and self.options:
            self.type=DataInfos.ENUM
        elif type(self.value)==int:
            self.type=DataInfos.INT
        elif type(self.value)==float:
            self.type=DataInfos.FLOAT
        elif type(self.value)==list:
            self.type=DataInfos.LIST
        else:
            self.type=DataInfos.STRING

    def getXMLString(self,indentLevel=4):
        pre="\t"*indentLevel
        pre="\n"+pre
        ret=""
        if self.value is not None:
            if self.type==DataInfos.LIST:
                ret+=pre+"<value>"+(",".join(self.value))+"</value>"
            else:
                ret+=pre+"<value>"+str(self.value)+"</value>"
        else:
            ret+=pre+"<value></value>"
        ret+=pre+"<type>"+self.type+"</type>"
        ret+=pre+"<category>"+self.category+"</category>"
        #ret+=pre+"<help>"+str(self.help)+"</help>"
        if self.options:
            ret+=pre+"<options>"+str(self.options)+"</options>"
        else:
            ret+=pre+"<options></options>"
        return ret
    
    def clone(self):
        ret=DataInfos(self.section,self.name,self.value,self.type,self.options,self.category,self.help)
        return ret
        